/*
 * Sistema.h
 *
 *  Created on: Nov 11, 2013
 *      Author: damian
 */

#ifndef SISTEMA_H_
#define SISTEMA_H_

#include <ctime>
#include <sstream>
#include <iomanip>
#include <vector>

#include "entidades/Usuario.h"
#include "entidades/Servicio.h"
#include "entidades/Consulta.h"
#include "entidades/Categoria.h"
#include "entidades/Cotizacion.h"
#include "../CapaLogica/HashExtensible/HashManager.h"
#include "../CapaLogica/Arbol/ArbolBMas.h"
#include "../CapaLogica/ListaInvertida/ListaInvertida.h"
#include "../Encriptacion/Encriptador.h"

#define BLOQUE_SIZE 512

#define INDICES_PATH "system_files/"
#define STOPWORDS_PATH "CapaLogica/ListaInvertida/stopWords.txt"

#define ID_BASE_CATEGORIAS 2000000
#define ID_BASE_SERVICIOS 3000000
#define ID_BASE_CONSULTAS 4000000
#define ID_BASE_COTIZACIONES 5000000

#define CLAVE_UNICA "TPDATOS2013"  // para encriptar contraseñas de usuarios

using std::vector;
using std::string;

class Sistema {
private:
	HashManager* hashUsuarios;
	HashManager* hashServicios;
	HashManager* hashConsultas;
	HashManager* hashCategorias;
	HashManager* hashCotizaciones;
	ArbolBMas* indiceServiciosPorProveedor;
	ArbolBMas* indiceServiciosPorCategoria;
	ArbolBMas* indiceConsultasPorServicio;
	ArbolBMas* indiceCotizacionesPorServicio;
	ArbolBMas* indiceCategorias;
	ListaInvertida* indiceInvertidoServicios;
	ListaInvertida* indiceInvertidoConsultas;
	ListaInvertida* indiceInvertidoCategorias;
	Encriptador* encriptador;
	Encriptador* encriptadorCotizaciones;

	// carpeta donde se guardan los archivos creados por el sistema
	const string sys_files_path;

public:
	Sistema();
	~Sistema();

	/*
	 * El usuario esta registrado en el sistema y quiere validar su contraseña
	 * para loguearse. Devuelve el tipo de usuario que se logueó.
	 */
	char loguearUsuario(int dni, string pass);

	/*
	 * Verifica que todos los caracteres de la contraseña sean válidos
	 * para poder encriptarla completa
	 */
	bool passwordValida(string nueva);

	/* U1 */
	bool registrarUsuario(Usuario& nuevo);
	/* U2 */
	bool recuperarUsuario(int dni, Usuario& recuperado);
	bool modificarUsuario(Usuario& modificado);
	/* U3 */
	bool eliminarUsuario(int dni);
	/* U4 */
	void consultarServiciosPorProveedor(int idProveedor, vector<Servicio>*);
	bool consultarServicioPorId(int idServicio, Servicio& consultado);
	void consultarServiciosPorCategoria(string categoria, vector<Servicio>*);
	void consultarServicioPorPalabraClave(string palabra, vector<Servicio>*);
	/* U5 */
	bool realizarConsulta(int idServicio, int idUsuario, string texto);
	bool crearConsulta(Consulta& nueva);
	/* U6 */
	bool realizarPedidoDeCotizacion(int idServicio, int idUsuario, string texto);
	bool crearCotizacion(Cotizacion& nueva);

	/* P1 */
	bool registrarProveedor(int dni);
	/* P2 y P3 usa el mismo metodo que U2 y U3 */
	/* P4 */
	int getIdIncrementalDeServicios();
	bool crearServicio(Servicio& nuevo);
	/* P5 */
	void listarCategorias(vector<Categoria>*);
	void listarCategoriasPorPalabraClave(string palabra, vector<Categoria>*);
	bool asociarServicioACategoria(int idServicio, int idCategoria);
	/* P6 */
	void listarConsultasPorServicio(int idServicio, vector<Consulta>*);
	bool responderConsulta(int idConsulta, string texto);
	/* P7 */
	bool eliminarServicio(int idServicio);
	/* P8 */
	void listarCotizacionesPorServicio(int idServicio, vector<Cotizacion>*);

	/* A1 */
	bool crearAdministradorPrincipal();
	/* A2 */
	bool registrarAdministrador(int dni);
	/* A3 usa el mismo metodo que U3 */
	/* A4 */
	int getIdIncrementalDeCategorias();
	bool crearCategoria(Categoria& nueva);
	/* A5 */
	bool crearCategorias(string archivoCategorias);
	/* A6 */
	bool recuperarCategoria(int idCategoria, Categoria& recuperada);
	bool modificarCategoria(Categoria& modificada);
	/* A7 */
	bool eliminarCategoria(int idCategoria);
	/* A8 */
	void listarConsultas(vector<Consulta>*);
	void listarConsultasPorPalabraClave(string palabra, vector<Consulta>*);
	bool moderarConsultas(int idConsulta, bool mostrar);
	/* A9 */
	string recuperarPassword(int dni);
	bool modificarPassword(int dni, string pass);

private:
	string getFecha();
	string getHora();
};

#endif /* SISTEMA_H_ */
